#!/usr/bin/python3
# -*- coding: utf-8; tab-width: 4; indent-tabs-mode: t -*-

import os
import re
import sys
import pathlib
from gstage4._patcher import RepoPatcher


def get_int_or_none(s):
    if s is None:
        return None
    try:
        return int(s)
    except ValueError:
        return None


def make_conf_get_var(buf, var_name):
    m = re.search("^%s=\"(.*)\"$" % (var_name), buf, re.MULTILINE)
    if m is None:
        return ""
    varVal = m.group(1)

    while True:
        m = re.search("\\${(\\S+)?}", varVal)
        if m is None:
            break
        varName2 = m.group(1)
        varVal2 = make_conf_get_var(buf, varName2)
        if varVal2 is None:
            varVal2 = ""

        varVal = varVal.replace(m.group(0), varVal2)

    return varVal


def usage():
    print("Usage:")
    print("  %s <repository name> <sync uri> <location>" % (sys.argv[0]))


if __name__ == "__main__":
    if len(sys.argv) == 2 and sys.argv[1] == "--help":
        usage()
        sys.exit(0)

    if len(sys.argv) < 4:
        usage()
        sys.exit(1)

    sourceDir = sys.argv[0] + ".d"
    targetDirRepoName = sys.argv[1]
    syncUrl = sys.argv[2]                   # not used, only to fulfill gentoo postsync.d script spec
    targetDir = sys.argv[3]

    jobNumber = None
    loadAverage = None
    if True:
        try:
            buf = pathlib.Path("/etc/portage/make.conf").read_text()
        except FileNotFound:
            buf = ""
        if True:
            value = make_conf_get_var(buf, "MAKEOPTS")
            if jobNumber is None:
                m = re.search("\\B--jobs(=([0-9]+))?\\b", value)
                if m is not None:
                    jobNumber = get_int_or_none(m.group(2))
            if jobNumber is None:
                m = re.search("\\B-j([0-9]+)?\\b", value)
                if m is not None:
                    jobNumber = get_int_or_none(m.group(1))
            if loadAverage is None:
                m = re.search("\\B--load-average(=([0-9\\.]+))?\\b", value)
                if m is not None:
                    loadAverage = get_int_or_none(m.group(2))
            if loadAverage is None:
                m = re.search("\\B-l([0-9]+)?\\b", value)
                if m is not None:
                    loadAverage = get_int_or_none(m.group(1))
        if jobNumber is None or loadAverage is None:
            value = make_conf_get_var(buf, "EMERGE_DEFAULT_OPTS")
            if jobNumber is None:
                m = re.search("\\B--jobs(=([0-9]+))?\\b", value)
                if m is not None:
                    jobNumber = get_int_or_none(m.group(2))
            if loadAverage is None:
                m = re.search("\\B--load-average(=([0-9\\.]+))?\\b", value)
                if m is not None:
                    loadAverage = get_int_or_none(m.group(2))
    if jobNumber is None:
        jobNumber = 1

    patcher = RepoPatcher(jobNumber=jobNumber, loadAverage=loadAverage)
    patchDirList = [os.path.join(sourceDir, x) for x in os.listdir(sourceDir)]
    patchDirList = patcher.filter_patch_dir_list(patchDirList, targetDirRepoName)
    if len(patchDirList) > 0:
        print("Patching...")
        pendingDstDirList = patcher.patch(targetDir, patchDirList, targetDirRepoName)
        for x in patcher.warn_or_err_list:
            if x.warn_or_err:
                print("Warning: %s" % (x.msg))
            else:
                print("Error: %s" % (x.msg), file=sys.stderr)
        if any(not x.warn_or_err for x in patcher.warn_or_err_list):
            sys.exit(1)
        if len(pendingDstDirList) > 0:
            patcher.generateManifest(targetDir, pendingDstDirList)
        print("Done.")
